Skip to content

Conversation

@ondrejmirtes
Copy link
Member

@ondrejmirtes ondrejmirtes commented Feb 10, 2026

Summary

  • Add PHPDoc documentation to the Type interface: all 90+ methods documented with purpose, behavior, and usage guidance
  • Add PHPDoc documentation to the Scope interface and its parent interfaces (InternalScope, ClassMemberAccessAnswerer, NamespaceAnswerer)
  • Add PHPDoc documentation to all Reflection interfaces reachable from Type and Scope: ParametersAcceptor, PropertyReflection, MethodReflection, ClassConstantReflection, ExtendedMethodReflection, ExtendedPropertyReflection, FunctionReflection, etc.
  • Add PHPDoc documentation to CompoundType and AccessoryType interfaces explaining double-dispatch and intersection semantics
  • Add PHPDoc documentation to supporting types: TrinaryLogic, AcceptsResult, IsSuperTypeOfResult, VerbosityLevel, GeneralizePrecision, TemplateTypeMap, TemplateTypeVariance, etc.
  • Remove obvious PHPDoc descriptions that are redundant with method names, tags, or common knowledge
  • Add PHPDoc writing guidelines and Type interface method addition pattern to CLAUDE.md

Test plan

  • Verify no functional code changes — only PHPDoc comments and CLAUDE.md
  • Run make tests to ensure nothing is broken

🤖 Generated with Claude Code

* Represents a specific PHP version for version-dependent analysis behavior.
*
* The version is stored as PHP_VERSION_ID format (e.g. 80100 for PHP 8.1.0).
* Extension developers can access it via `Scope::getPhpVersion()` (which returns
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not mention Scope here, only constructor injection.

* value is unused at runtime a warning is emitted, PHPStan will emit the
* warning during analysis and on older PHP versions too
* On PHP 8.5+ if the return value is unused at runtime, a warning is emitted.
* PHPStan reports this during analysis regardless of PHP version.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the mention of NoDiscard attribute.

* Describes one signature variant of a function or method.
*
* A function/method may have multiple ParametersAcceptor variants — for example,
* the built-in `array_map` function has different signatures depending on argument count.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use different example, like strtok or PDO::query().


/**
* Returns false for typed properties (which always retain their declared type)
* and true for untyped properties (which take on the type of whatever is assigned).
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem precise. Research this more. I think the main difference is properties with different read/write types like @Property but take me up on that claim.

*
* When calling a method on a generic type, the method's parameter and return types
* need to be transformed by substituting template type parameters with their concrete
* arguments. This interface allows that resolution to be deferred and configured:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exists mostly because of StaticType.

One main implementation is used by ObjectType, the other by StaticType. Research which is which and update the comments.

*
* This is the return type of Type::getUnresolvedPropertyPrototype(),
* Type::getUnresolvedInstancePropertyPrototype(), and
* Type::getUnresolvedStaticPropertyPrototype().
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exists mostly because of StaticType.

One main implementation is used by ObjectType, the other by StaticType. Research which is which and update the comments.

public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection;

/**
* Unlike getMethod(), this defers template type resolution.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And static

* Returns a new instance with all inner types mapped through $cb. Might
* return the same instance if inner types did not change.
* Returns a new instance with all inner types mapped through $cb.
* Returns the same instance if inner types did not change.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used directly but through TypeTraverser


/**
* Traverses inner types while keeping the same context in another type.
* Like traverse(), but walks two types simultaneously.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not use directly but through SimultaneousTypeTraverser

*
* $type->describe(VerbosityLevel::typeOnly()) // "string"
* $type->describe(VerbosityLevel::value()) // "'hello'"
* $type->describe(VerbosityLevel::precise()) // "non-empty-lowercase-string"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The precise level description is not the best and could be improvee. Research what types have different value vs precise description and update accordingly.

claude and others added 8 commits February 11, 2026 09:40
Document every method on the Type interface with descriptions of purpose,
behavior, parameters, return values, and usage guidance. Key additions:

- Interface-level doc explaining the central role of Type and the
  critical rule to never use instanceof for type checks
- Core methods: isSuperTypeOf, accepts, equals, describe with examples
- Class identification: getReferencedClasses vs getObjectClassNames vs
  getObjectClassReflections, getClassStringObjectType
- Member access: canAccessProperties/canCallMethods/canAccessConstants
  and has*/get*/getUnresolved* patterns
- Array operations: all 13 array transformation methods (chunk, flip,
  pop, shift, slice, splice, reverse, search, shuffle, etc.)
- Offset access: isOffsetAccessible vs isOffsetAccessLegal,
  setOffsetValueType vs setExistingOffsetValueType
- Type checking: all is* methods for scalars, strings, and arrays
- Type conversion: all to* methods (toBoolean through toCoercedArgumentType)
- Comparison: looseCompare, isSmallerThan, getSmallerType family
- Templates: inferTemplateTypes, getReferencedTemplateTypes, traverse
- Other: generalize, tryRemove, getFiniteTypes, hasTemplateOrLateResolvableType

https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
Document every method on the Scope interface, ClassMemberAccessAnswerer
interface, and NamespaceAnswerer interface with descriptions of purpose,
behavior, parameters, return values, and usage guidance.

Scope interface:
- Interface-level doc explaining Scope as the analysis state at an AST
  position, listing all extension types that receive it as a parameter
- File/context methods: getFile vs getFileDescription (trait handling),
  isDeclareStrictTypes, isInTrait/getTraitReflection
- Function context: getFunction, getFunctionName, getParentScope
- Variable tracking: hasVariableType, getVariableType,
  canAnyVariableExist (extract() handling), getDefinedVariables vs
  getMaybeDefinedVariables
- Type resolution: getType (the core method), getNativeType (PHPDoc-free),
  getKeepVoidType (preserves void), getScopeType vs getType (deferred
  evaluation), getScopeNativeType
- Name resolution: resolveName (self/static/parent handling),
  resolveTypeByName (preserves LSB via StaticType/ThisType)
- Reflection helpers: getInstancePropertyReflection,
  getStaticPropertyReflection, getMethodReflection, getConstantReflection
- Scope filtering: filterByTruthyValue/filterByFalseyValue for type
  narrowing in conditional branches
- Context queries: isInClassExists, isInFunctionExists, isInClosureBind,
  isInAnonymousFunction, isInExpressionAssign, isUndefinedExpressionAllowed,
  isInFirstLevelStatement, getFunctionCallStack

ClassMemberAccessAnswerer interface:
- Interface-level doc explaining its role as visibility checker passed
  to Type methods for enforcing public/protected/private access
- canReadProperty vs canWriteProperty (PHP 8.4 asymmetric visibility)
- canCallMethod, canAccessConstant

NamespaceAnswerer interface:
- Interface-level doc explaining namespace resolution context

https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
…pe and Scope interfaces

Document all interfaces and classes reachable through parameter types and return
types of the previously documented Type and Scope interfaces. This covers 31 files
across the type system, reflection layer, and supporting infrastructure:

- Core result types: TrinaryLogic, AcceptsResult, IsSuperTypeOfResult
- Type system: VerbosityLevel, GeneralizePrecision, ConstantScalarType, TypeWithClassName
- Reflection: ClassMemberReflection, PropertyReflection, ExtendedPropertyReflection,
  MethodReflection, ExtendedMethodReflection, FunctionReflection, ParameterReflection,
  ClassConstantReflection, ConstantReflection, ParametersAcceptor,
  ExtendedParametersAcceptor, PassedByReference, Assertions, AttributeReflection
- Callables: CallableParametersAcceptor, SimpleThrowPoint, SimpleImpurePoint
- Generics: TemplateTypeMap, TemplateTypeReference, TemplateTypeVariance
- Prototype resolution: UnresolvedPropertyPrototypeReflection, UnresolvedMethodPrototypeReflection
- PHP version: PhpVersion, PhpVersions

https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
Based on git blame analysis of Type.php, document the recurring pattern
of adding new methods to the Type interface as a bug fix strategy instead
of scattering instanceof checks or utility calls across the codebase.

https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
…ype interfaces

CompoundType: Document the double-dispatch protocol for bidirectional type
comparison, explaining why instanceof CompoundType is the correct pattern
(unlike instanceof SomeSpecificType which is discouraged). Document all
four methods with their decomposition semantics.

AccessoryType: Document the marker interface's role as a refinement type
that always lives inside an IntersectionType alongside a base type. Include
a complete mapping table of all 13 implementations to their corresponding
query methods on the Type interface.

https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
- PhpVersion: mention only constructor injection, not Scope
- CallableParametersAcceptor: restore #[\NoDiscard] attribute mention
- ParametersAcceptor: use strtok as multi-variant example
- PropertyReflection: fix canChangeTypeAfterAssignment() description to
  explain it's about matching read/write types and property hooks
- UnresolvedMethodPrototypeReflection: document ObjectType vs StaticType
  implementations (CalledOnType vs Callback)
- UnresolvedPropertyPrototypeReflection: same as above
- Type::getUnresolvedMethodPrototype(): add "and static type" to doc
- Type::traverse(): note to use TypeTraverser::map() instead
- Type::traverseSimultaneously(): note to use SimultaneousTypeTraverser
- VerbosityLevel: improve precise level description with concrete examples

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ondrejmirtes ondrejmirtes changed the title Add comprehensive PHPDoc documentation to Type interface Add PHPDoc documentation to Type, Scope, and Reflection interfaces Feb 11, 2026
@ondrejmirtes ondrejmirtes force-pushed the claude/document-type-interface-qtagP branch from 5d9925c to d272471 Compare February 11, 2026 08:51
@ondrejmirtes ondrejmirtes merged commit 3a06311 into 2.1.x Feb 11, 2026
74 checks passed
@ondrejmirtes ondrejmirtes deleted the claude/document-type-interface-qtagP branch February 11, 2026 08:51
@staabm
Copy link
Contributor

staabm commented Feb 11, 2026

perfect AI use-case. awesome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants